using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using System.Collections.Generic;

namespace IQIGame.Onigao.Logic
{
    /// <summary>
    /// 服务管理器，每一个实体都会持有一个
    /// </summary>
    public class ServiceManager : IReusableClass
    {
        private Dictionary<ServiceTriggerType, List<LevelService>> _serviceTypeMap = new Dictionary<ServiceTriggerType, List<LevelService>>();
        /// <summary>
        /// 可能是Player/Hero/Entity
        /// </summary>
        private BaseLevelFunctionHost _host;
        /// <summary>
        /// 临时执行列表，没有用队列是因为策划需求在执行中移除服务需要立马生效，所以需要指定index移除正在执行的列表
        /// 没有直接使用_serviceTypeMap内部的列表是因为在遍历执行的过程中可能会修改_serviceTypeMap
        /// </summary>
        private List<LevelService> _reversedExecutingServices = new List<LevelService>();

        public bool haveMoveTrigger { get; set; }
        public int serviceCount
        {
            get
            {
                int count = 0;
                foreach (var item in _serviceTypeMap)
                {
                    count += item.Value.Count;
                }
                return count;
            }
        }
        public uint MaxStore => 50;

        public void SetHost(BaseLevelFunctionHost hostEntity)
        {
            _host = hostEntity;
        }

        public void Refresh(IReadOnlyList<int> services)
        {
            haveMoveTrigger = false;
            ClearServices();
            if (services == null)
            {
                return;
            }
            for (int i = 0; i < services.Count; i++)
            {
                LevelService service = ClassPool.Get<LevelService>();
                service.Init(services[i], _host);
                ServiceTriggerType triggerType = service.GetTriggerType();
                if (!_serviceTypeMap.TryGetValue(triggerType, out var serviceList))
                {
                    serviceList = ListPool<LevelService>.Get();
                    _serviceTypeMap.Add(triggerType, serviceList);
                }
                serviceList.Add(service);

                if (triggerType == ServiceTriggerType.MoveInRange)
                {
                    haveMoveTrigger = true;
                }
            }
        }

        /// <summary>
        /// 清除所有服务
        /// </summary>
        private void ClearServices()
        {
            if (_serviceTypeMap == null)
            {
                return;
            }
            foreach (var item in _serviceTypeMap)
            {
                for (int i = 0; i < item.Value.Count; i++)
                {
                    ClassPool.Put(item.Value[i]);
                }
                item.Value.Clear();
                ListPool<LevelService>.Put(item.Value);
            }
            _serviceTypeMap.Clear();
        }

        /// <summary>
        /// 触发服务
        /// </summary>
        /// <param name="player"></param>
        /// <param name="triggerType"></param>
        /// <param name="objectParam"></param>
        /// <returns>是否有任意执行成功生效</returns>
        public bool TryTrigger(LevelPlayer player, ServiceTriggerType triggerType, object objectParam = null, TrigValueTypeParam valueTypeParam = default)
        {
            bool hasSuccess = false;
            _reversedExecutingServices.Clear();
            if (_serviceTypeMap.TryGetValue(triggerType, out var serviceList))
            {
                //填充临时执行列表，反着添加是因为下方while里RemoveAt从最后一个开始，性能更好，没有使用队列原因参看字段注释
                for (int i = serviceList.Count - 1; i >= 0; i--)
                {
                    _reversedExecutingServices.Add(serviceList[i]);
                }
                while (_reversedExecutingServices.Count > 0)
                {
                    int index = _reversedExecutingServices.Count - 1;
                    LevelService service = _reversedExecutingServices[index];
                    _reversedExecutingServices.RemoveAt(index);

                    bool triggerSuccess = triggerType == ServiceTriggerType.None || service.TryTrigger(player, objectParam, valueTypeParam);
                    if (triggerSuccess)
                    {
                        hasSuccess = service.Execute(player) > 0 || hasSuccess;
                    }
                }
            }
            return hasSuccess;
        }

        /// <summary>
        /// 清除所有
        /// 如果还有执行的服务也清除
        /// </summary>
        public void ClearAll()
        {
            ClearServices();
            _reversedExecutingServices.Clear();
        }

        public void Dispose()
        {
            ClearAll();
            _host = null;
            haveMoveTrigger = false;
        }

        //public void AddService(IReadOnlyList<int> services)
        //{
        //    if (services == null || services.Count == 0)
        //    {
        //        LogicLog.LogError($"增加的服务列表为空");
        //        return;
        //    }
        //    for (int i = 0; i < services.Count; i++)
        //    {
        //        LevelService service = ClassPool.Get<LevelService>();
        //        service.Init(services[i], _host);
        //        if (!_serviceTypeMap.TryGetValue(service.GetTriggerType(), out var serviceList))
        //        {
        //            serviceList = ListPool<LevelService>.Get();
        //            _serviceTypeMap.Add(service.GetTriggerType(), serviceList);
        //        }
        //        serviceList.Add(service);
        //    }
        //}

        //public void RemoveService(IReadOnlyList<int> serviceCids)
        //{
        //    if (serviceCids == null || serviceCids.Count == 0)
        //    {
        //        ClearServices();
        //    }
        //    else
        //    {
        //        foreach (var item in _serviceTypeMap)
        //        {
        //            for (int i = item.Value.Count - 1; i >= 0; i--)
        //            {
        //                LevelService service = item.Value[i];
        //                int index = -1;
        //                for (int j = 0; j < serviceCids.Count; j++)
        //                {
        //                    if (serviceCids[j] == service.config.id)
        //                    {
        //                        index = j;
        //                        break;
        //                    }
        //                }
        //                if (index != -1)
        //                {
        //                    item.Value.RemoveAt(i);
        //                    ClassPool.Put(service);
        //                    if (_reversedExecutingServices.IndexOf(service) != -1)
        //                    {
        //                        _reversedExecutingServices.Remove(service);
        //                    }
        //                }
        //                else
        //                {
        //                    LogicLog.LogWarning($"警告！删除服务{service.config.id}失败，不再当前服务列表中。");
        //                }
        //            }
        //        }
        //    }
        //}

        public void SetServiceUnitEnabled(int serviceId, int unitIndex, bool isEnabled)
        {
            foreach (var kv in _serviceTypeMap)
            {
                bool found = false;
                foreach (var service in kv.Value)
                {
                    if (service.config.id == serviceId)
                    {
                        service.SetUnitEnabled(unitIndex, isEnabled);
                        found = true;
                        break;
                    }
                }
                if (found)
                {
                    break;
                }
            }
        }

        public List<int> ToServiceCidList()
        {
            List<int> serviceCids = new List<int>();
            foreach (var item in _serviceTypeMap)
            {
                for (int i = 0; i < item.Value.Count; i++)
                {
                    serviceCids.Add(item.Value[i].config.id);
                }
            }
            return serviceCids;
        }

        public void OnReset()
        {
            Dispose();
        }
    }
}
